/*
* Poppy Game Engine - https://pgetemplate.googlecode.com/svn/
* -----------------------------------------------------------------------
* Licensed under the BSD license, see LICENSE in PSPSDK root for details.
*
* Copyright (c) 2008 Poppy
*/

#include "stdafx.h"
#include "CWinInit.h"
#include "CPSPDriver.h"
#include "DriverInternal.h"

namespace PGERenderer
{

	void CPSPDriver::InitGraphicSystem()
	{
		assert(!m_bIsInited);
		assert(!m_pData);
		m_pData = new CGraphicSystemData();
		if(m_pData->m_cWinInit.InitWindow())
		{
			if( m_pData->m_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) )
			{
				m_pData->m_sD3DPresentPara.BackBufferWidth				= PSP_SCREEN_WIDTH;
				m_pData->m_sD3DPresentPara.BackBufferHeight				= PSP_SCREEN_HEIGHT;
				m_pData->m_sD3DPresentPara.BackBufferFormat				= D3DFMT_A8R8G8B8;
				m_pData->m_sD3DPresentPara.BackBufferCount				= 1;
				m_pData->m_sD3DPresentPara.SwapEffect					= D3DSWAPEFFECT_DISCARD;
				m_pData->m_sD3DPresentPara.hDeviceWindow				= m_pData->m_cWinInit.mHWnd;
				m_pData->m_sD3DPresentPara.Windowed						= TRUE;
				m_pData->m_sD3DPresentPara.EnableAutoDepthStencil		= TRUE;
				m_pData->m_sD3DPresentPara.AutoDepthStencilFormat		= D3DFMT_D24S8;
				m_pData->m_sD3DPresentPara.Flags						= NULL;
				m_pData->m_sD3DPresentPara.FullScreen_RefreshRateInHz	= D3DPRESENT_RATE_DEFAULT;
				m_pData->m_sD3DPresentPara.PresentationInterval			= D3DPRESENT_INTERVAL_IMMEDIATE;

				if( SUCCEEDED( m_pData->m_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_pData->m_cWinInit.mHWnd,
					D3DCREATE_HARDWARE_VERTEXPROCESSING,
					&m_pData->m_sD3DPresentPara, &m_pData->m_pD3DDevice ) ) )
				{
					ShowWindow(m_pData->m_cWinInit.mHWnd, SW_SHOW);
					UpdateWindow(m_pData->m_cWinInit.mHWnd);
					Setup();
					if( BeginScene() )
					{
						EndScene();
					}
					m_bIsInited = true;
					if( FAILED(m_pData->m_pD3DDevice->CreateVertexBuffer( 262144, D3DUSAGE_DYNAMIC, VERTEX_TYPE_2D_COLOR, D3DPOOL_DEFAULT, &m_pData->m_pMainVBuffer, NULL ) ) )
						assert(0);
					if( FAILED(m_pData->m_pD3DDevice->CreateIndexBuffer( 262144, D3DUSAGE_DYNAMIC, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pData->m_pMainIBuffer, NULL ) ) )
						assert(0);
					return;
				}
			}
		}
		assert(0);
	}

	void CPSPDriver::TermGraphicSystem()
	{
		assert(m_bIsInited);
		assert(m_pData);
		m_pData->m_cWinInit.DestoryWindow();
		SAFE_RELEASE(m_pData->m_pMainVBuffer);
		SAFE_RELEASE(m_pData->m_pMainIBuffer);
		SAFE_RELEASE(m_pData->m_pD3D);
		SAFE_RELEASE(m_pData->m_pD3DDevice);
		SAFE_DELETE(m_pData);
		m_bIsInited = false;
	}

	bool CPSPDriver::BeginScene()
	{
		if( PeekMessage( &m_pData->m_sMessage, NULL, 0U, 0U, PM_REMOVE ) )
		{
			TranslateMessage( &m_pData->m_sMessage );
			DispatchMessage( &m_pData->m_sMessage );
			return false;
		}
		else
		{
			Clear();
			m_pData->m_uVBOffset = 0;
			m_pData->m_uIBOffset = 0;
			return SUCCEEDED( m_pData->m_pD3DDevice->BeginScene() );
		}
	}

	void CPSPDriver::EndScene()
	{
		m_pData->m_pD3DDevice->EndScene();
	}

	void CPSPDriver::Present()
	{
		m_pData->m_pD3DDevice->Present( NULL, NULL, NULL, NULL );
	}

	void CPSPDriver::Clear()
	{
		m_pData->m_pD3DDevice->Clear( 0, NULL, m_pData->m_iClearArea, m_pData->m_uClearColor, m_pData->m_fClearDepth, m_pData->m_uClearStencil );
	}

	void CPSPDriver::DepthRange(int near, int far)
	{

	}

	void CPSPDriver::FrontFace(int order)
	{

	}

	void CPSPDriver::ShadeModel(int mode)
	{

	}

	void CPSPDriver::ClearState(EClearFlag flag, unsigned int color)
	{
		switch(flag)
		{
		case CLEAR_COLOR:
			m_pData->m_uClearColor = color;
			break;
		case CLEAR_STENCIL:
			m_pData->m_uClearStencil = color;
			break;
		case CLEAR_COLOR_STENCIL:
			m_pData->m_uClearColor = color & 0xffffff;
			m_pData->m_uClearStencil = (color & 0xff000000)>>24 ;
			break;
		case CLEAR_DEPTH:
			m_pData->m_fClearDepth = ((float)color)/65535.f;
			break;
		case CLEAR_AREA:
			break;
		}
	}

	void CPSPDriver::DrawRegion(int x, int y, int width, int height)
	{

	}

	void CPSPDriver::SetDither(const int* matrix)
	{

	}

	void CPSPDriver::PatchDivide(unsigned int ulevel, unsigned int vlevel)
	{

	}

	void CPSPDriver::ColorMaterial(int  components)
	{

	}

	void CPSPDriver::Specular(float power)
	{

	}

	void CPSPDriver::TexScale(float u, float v)
	{

	}

	void CPSPDriver::Offset(unsigned int x, unsigned int y)
	{

	}

	void CPSPDriver::Viewport(int cx, int cy, int width, int height)
	{

	}

	void CPSPDriver::Scissor(int x, int y, int w, int h)
	{

	}

	void CPSPDriver::Start() {}

	void CPSPDriver::SetBuffers() {}

	void CPSPDriver::Setup()
	{

	}

	void CPSPDriver::SendCommandi(int cmd, int argument) {}

	void CPSPDriver::SendCommandf(int cmd, float argument) {}

	void CPSPDriver::CommandStall() {}
	
	void* CPSPDriver::GetMemory(int size)
	{
		return 0;
	}

	void CPSPDriver::SetVertexType(unsigned int vt, unsigned int vtsize)
	{
		m_pData->m_pD3DDevice->SetFVF(vt);
		m_pData->m_uVertexSize = vtsize;
	}

	void CPSPDriver::DrawVertex(PGEPRIMITIVE_TYPE prim, unsigned int count, LPVERTEX_BUFFER vertices)
	{
		m_pData->m_pD3DDevice->SetStreamSource( 0, vertices, 0, m_pData->m_uVertexSize );
		m_pData->m_pD3DDevice->DrawPrimitive( (D3DPRIMITIVETYPE)prim, 0, count );
	}

	void CPSPDriver::DrawIndex(PGEPRIMITIVE_TYPE prim, unsigned int count, unsigned int vertexs, LPVERTEX_BUFFER vertices, LPINDEX_BUFFER indices)
	{
		m_pData->m_pD3DDevice->SetStreamSource( 0, vertices, 0, m_pData->m_uVertexSize );
		m_pData->m_pD3DDevice->SetIndices( indices );
		m_pData->m_pD3DDevice->DrawIndexedPrimitive( (D3DPRIMITIVETYPE)prim, 0, 0, vertexs, 0, count );
	}

}



